package org.goobs.database;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;


public class Table {

	private Database parent;
	private String name;
	private Set<String> columns = null;

	protected Table(String name, Database parent) {
		this.parent = parent;
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public Database getDatabase() {
		return parent;
	}

	public Set<String> getColumns() {
		if (columns != null) {
			return columns;
		}
		HashSet<String> rtn = new HashSet<String>();
		if (!parent.runQuery("SELECT * FROM " + name)) {
			return null;
		}
		try {
			ResultSetMetaData meta = parent.getLastStatementMetaData();
			int columnIndex = meta.getColumnCount();
			while (columnIndex > 0) {
				rtn.add(meta.getColumnName(columnIndex));
				columnIndex--;
			}
		} catch (SQLException e) {
			return null;
		}
		this.columns = rtn;
		return rtn;
	}

	public int getRowCount() {
		if(!parent.runQuery("SELECT COUNT(*) FROM " + name)){
			return -1;
		}
		try {
			ResultSet rs = parent.getLastStatementResult();
			rs.next();
			return rs.getInt(1);
		} catch (SQLException e) {
			return -1;
		}
	}
	
	public boolean addRow(DatabaseRow toAdd, String ignoreWhen){
		ResultFactory fact = where(ignoreWhen);
		if(fact.hasMoreRows()){
			//(ignore since it's already there)
			return false;
		}else{
			return addRow(toAdd);
		}
	}
	
	public boolean addRow(DatabaseRow toAdd){
		Map <String, Object> data = toAdd.export();
		StringBuilder b = new StringBuilder();
		
		//--Prepare the statement
		b.append("INSERT INTO ").append(name).append(" (");
		for(String key : data.keySet()){
			b.append(key + ", ");
		}
		String tmp = b.substring(0, b.length()-2);
		b = new StringBuilder(tmp);
		b.append(") VALUES (");
		for(String key : data.keySet()){
			Object value = data.get(key);
			if(value instanceof String){
				value = "'" + value + "'";
			}
			b.append(value + ", ");
		}
		tmp = b.substring(0, b.length()-2);
		b = new StringBuilder(tmp);
		b.append(")");
		
		//--Execute the statement
		String query = b.toString();
		return parent.runQuery(query);
	}
	
	public ResultFactory getRows(String field, String match){
		return where(field + "=\"" + match + "\"");
	}
	
	public boolean getFirstRow(String field, String match, DatabaseRow toFill){
		return whereFirst(field + "=" + match, toFill);
	}
	
	public ResultFactory getAllRows(){
		if(!parent.runQuery("SELECT * FROM " + name)){
			return null;
		}
		ResultSet rs = parent.getLastStatementResult();
		ResultSetMetaData meta = parent.getLastStatementMetaData();
		return new ResultFactory(rs, meta, this);
	}
	
	public ResultFactory where(String matches){
		if(!parent.runQuery("SELECT * FROM " + name + " WHERE " + matches)){
			return null;
		}
		ResultSet rs = parent.getLastStatementResult();
		ResultSetMetaData meta = parent.getLastStatementMetaData();
		return new ResultFactory(rs, meta, this);
	}
	
	public boolean whereFirst(String matches, DatabaseRow toFill){
		ResultFactory fact = where(matches);
		if(!fact.hasMoreRows()){
			return false;
		}
		return fact.fillObject(toFill);
	}

	public String toString() {
		return "[Table: " + name + "]";
	}
}
